<template>

    <div class="emb-edit-preview">
        <div class="emb-edit-background" :class="{ grabbing: !!mouse }" @mousedown="onMousedown($event)"
             @touchstart="onMousedown($event)" @mousewheel="onMousewheel"></div>
        <div class="emb-edit-stitches" :class="{ grabbing: !!mouse }" :style="canvasStyle"
             @mousedown="onMousedown($event)" @mouseup='onMouseup($event)' @touchstart="onMousedown($event)"
             @mousewheel="onMousewheel" @click="onDstClick($event)">
            <div class="emb-edit-canvas" />
            <div class="emb-edit-hover" />
        </div>
        <div class="emb-edit-platen" :style="platenStyle" v-if="platen" @click="onDstClick($event)">
            <DesignerEmbPlatenName :name="(platen || {}).name"  />
        </div>
        <UxInputSlider v-model="scaleSlider" :step="1" :min="range.min * 100" :max="range.max * 100" />
    </div>
</template>

<script>
import { mapGetters } from "vuex";
import { colors, Pattern } from "@/utils/EmbroideryPattern.js";
import { getStitchesByBase64 } from "@/utils/EmbroideryDst.js";
import { writeCanvas, writeHovers } from "@/utils/EmbroideryCanvas.js";

export default {
    props: {
        stitches: { type: String, default: () => '' },
        colors: { type: String, default: () => '' },
        value: { type: Number, default: () => -1 },
        platen: { type: Object, default: () => null },
    },
    data () {
        return {
            mouse: null,
            offset: { scale: 1, x: 0, y: 0 },
            range: { min: 1, max: 5 },
            outer: { width: 0, height: 0, left: 0, top: 0 },
            inner: { width: 0, height: 0 },
            padding: 80,
            hovers: [],
        };
    },

    computed: {
        ...mapGetters("designer", {
            platens: "getPlatens",
            pieces: "getPieces",
            activePiece: "getActivePiece",
            activeLayer: "getActiveLayer",
        }),

        // 容器尺寸
        contentSize () {

            const size = {
                width: 0,
                height: 0,
            }

            const outer_width = this.outer.width - 2 * this.padding
            const outer_height = this.outer.height - 2 * this.padding

            if (this.platen) {
                const platen_width = this.platen.width * 254 / 300;
                const platen_height = this.platen.height * 254 / 300;

                const platen_lay = platen_width > platen_height ? 1 : 0
                const inner_lay = this.inner.width > this.inner.height ? 1 : 0

                if (platen_lay == inner_lay) {

                    size.width = Math.max(outer_width, platen_width, this.inner.width)
                    size.height = Math.max(outer_height, platen_height, this.inner.height)

                } else {
                    size.width = Math.max(outer_width, platen_height, this.inner.width)
                    size.height = Math.max(outer_height, platen_width, this.inner.height)
                }

            } else {

                size.width = Math.max(outer_width, this.inner.width)
                size.height = Math.max(outer_height, this.inner.height)
            }

            const scale = Math.min(outer_width / size.width, outer_height / size.height) || 1


            return {
                scale: scale,
                width: this.outer.width * scale,
                height: this.outer.height * scale,
            }
        },


        // 版带
        canvasStyle () {

            const innerWidth = this.inner.width * this.contentSize.scale;
            const innerHeight = this.inner.height * this.contentSize.scale;
            const centerX = 0.5 * (this.outer.width - innerWidth)
            const centerY = 0.5 * (this.outer.height - innerHeight)
            const offsetX = centerX + this.offset.x
            const offsetY = centerY + this.offset.y

            return {
                width: 100 * innerWidth / this.outer.width + '%',
                height: 100 * innerHeight / this.outer.height + '%',
                left: 100 * offsetX / this.outer.width + '%',
                top: 100 * offsetY / this.outer.height + '%',
                transform: `scale(${this.offset.scale})`
            };
        },

        // 台板宽高
        platenStyle () {

            const platen_width = this.platen.width * 254 / 300;
            const platen_height = this.platen.height * 254 / 300;

            const platen_lay = platen_width > platen_height ? 1 : 0
            const inner_lay = this.inner.width > this.inner.height ? 1 : 0
            const inner_width = (platen_lay == inner_lay ? platen_width : platen_height) * this.contentSize.scale;
            const inner_height = (platen_lay == inner_lay ? platen_height : platen_width) * this.contentSize.scale;

            const centerX = 0.5 * (this.outer.width - inner_width)
            const centerY = 0.5 * (this.outer.height - inner_height)
            const offsetX = centerX + this.offset.x
            const offsetY = centerY + this.offset.y

            return {
                width: 100 * inner_width / this.outer.width + '%',
                height: 100 * inner_height / this.outer.height + '%',
                left: 100 * offsetX / this.outer.width + '%',
                top: 100 * offsetY / this.outer.height + '%',
                transform: `scale(${this.offset.scale})`
            };

        },

        dstFormat () {
            const codes = this.colors.split(',').filter(i => i)
            const stitches = this.stitches ? getStitchesByBase64(this.stitches) : []

            return {
                stitches: stitches,
                colors: codes.map(i => colors.find(c => c.code == i)).filter(i => i),
                stitches_count: stitches.length,
            }
        },


        scaleSlider: {
            get () {
                return this.offset.scale * 100
            },
            set (val) {
                this.offset.scale = val / 100
            }
        }
    },
    watch: {
        'colors' () {
            this.getPreview()
        },
        'stitches' () {
            this.getPreview()
            this.getHovers();
        },
        'value' () {
            const elem = this.$el.querySelectorAll('.emb-edit-hover canvas')
            const list = Array.prototype.slice.call(elem)

            list.map((el, index) => {
                if (index == this.value) {
                    el.style.display = 'block'
                } else {
                    el.style.display = 'none'
                }
            })
        }
    },
    methods: {

        getIn (val) {
            return (val * 0.1 * 0.0394).toFixed(1)
        },
        getPreview () {
            if (this.$el && this.stitches && this.stitches.length > 0) {
                const canvas = writeCanvas(this.dstFormat.stitches, this.dstFormat.colors)
                // const svg = writeSvg(this.dstFormat.stitches, this.dstFormat.colors)
                this.inner.width = canvas.width;
                this.inner.height = canvas.height;

                // this.bound = { left: svg.left, top: svg.top, right: svg.right, bottom: svg.bottom, width: svg.width, height: svg.height }
                // this.paths = svg.paths

                this.$el.querySelector('.emb-edit-canvas').innerHTML = ''
                this.$el.querySelector('.emb-edit-canvas').appendChild(canvas)
            } else {
                this.svg = ''
            }

        },

        getHovers () {
            this.hovers = writeHovers(this.dstFormat.stitches, this.dstFormat.colors)
            this.$el.querySelector('.emb-edit-hover').innerHTML = ''
            this.hovers.map(canvas => this.$el.querySelector('.emb-edit-hover').appendChild(canvas))
        },

        getSize () {

            if (this.$el) {
                const rect = this.$el.getBoundingClientRect()
                this.outer.width = rect.width;
                this.outer.height = rect.height;
                this.outer.left = rect.left;
                this.outer.top = rect.top;
            }
        },

        onMousewheel (event) {
            const delta = event.deltaY // 滚轮，向上滚一下是 -100，向下滚一下是 100
            const x = event.clientX - this.outer.left
            const y = event.clientY - this.outer.top
            const zoom = this.offset.scale * 0.999 ** delta

            this.offset.scale = Math.min(this.range.max, Math.max(this.range.min, zoom));
        },
        // 鼠标按下
        onMousedown (event) {

            event.preventDefault();
            event.stopPropagation();

            const touch = (event.targetTouches || [])[0];
            const clientX = touch ? touch.clientX : event.clientX;
            const clientY = touch ? touch.clientY : event.clientY;


            this.mouse = {
                clientX: clientX,
                clientY: clientY,
                offsetX: this.offset.x,
                offsetY: this.offset.y,
            }

        },
        // 鼠标移动
        // 要做节流处理，防止频繁操作
        onMousemove (event) {

            if (!this.mouse) { return; }

            event.preventDefault();
            event.stopPropagation();
            const touch = (event.targetTouches || [])[0];
            const clientX = touch ? touch.clientX : event.clientX;
            const clientY = touch ? touch.clientY : event.clientY;

            this.offset.x = this.mouse.offsetX + clientX - this.mouse.clientX
            this.offset.y = this.mouse.offsetY + clientY - this.mouse.clientY

        },
        // 鼠标弹起
        onMouseup (event) {
            if (this.mouse) {
                event.preventDefault();
                event.stopPropagation();
                // 如果太短
                this.mouse = null;
            }
        },

        onDstClick (event) {
            this.$emit('dstClick', event)
        },

        onMouseenter (path) {
            // this.$emit('input', path.index)
        },

        onMouseleave (index) {
            // this.$emit('input', -1)
        },

        // 重置
        doScaleInit () {
            this.offset.scale = 1;
            this.offset.x = 0;
            this.offset.y = 0;
        }

    },

    mounted () {
        setTimeout(() => this.getSize(), 0);
        this.getPreview()
        this.getHovers()
        window.addEventListener('resize', this.getSize)
        window.addEventListener('mousemove', this.onMousemove, false); // 鼠标移动
        window.addEventListener('mouseup', this.onMouseup, false); // 鼠标弹起
        window.addEventListener('touchmove', this.onMousemove, { passive: false }); // 鼠标移动
        window.addEventListener('touchend', this.onMouseup, { passive: false }); // 鼠标弹起
    },
    beforeDestroy () {
        window.removeEventListener('resize', this.getSize)
        window.removeEventListener('mousemove', this.onMousemove); // 鼠标移动
        window.removeEventListener('mouseup', this.onMouseup); // 鼠标弹起
        window.removeEventListener('touchmove', this.onMousemove); // 鼠标移动
        window.removeEventListener('touchend', this.onMouseup); // 鼠标弹起
    },
};
</script>

<style lang="scss" scoped>
.emb-edit-preview {
    position: absolute;
    left: 0;
    top: 0;
    width: 100%;
    height: 100%;

    .emb-edit-background {
        position: absolute;
        left: 0;
        top: 0;
        right: 0;
        bottom: 0;
        cursor: grab;

    }

    .emb-edit-stitches {
        position: absolute;
        left: 0;
        top: 0;
        right: 0;
        bottom: 0;
        cursor: grab;


        &::v-deep canvas {
            position: absolute;
            left: 0;
            top: 0;
            width: 100%;
            height: 100%;
        }

        .emb-edit-hover::v-deep canvas {
            display: none;
        }




    }

    .grabbing {
        cursor: grabbing;
    }

    .emb-edit-platen {
        position: absolute;
        left: 0;
        top: 0;
        box-sizing: border-box;
        border: 2px solid #555;

        &>.emb-platen-name {
            position: absolute;
            left: 0;
            top: -20px;
            font-family: Roboto, Roboto;
            font-weight: 500;
            font-size: 12px;
            color: #757575;
            line-height: 20px;
            pointer-events: none;
        }
    }

    &>p {
        display: flex;
        flex-direction: column;
        position: absolute;
        left: 20px;
        top: 20px;

        strong {
            font-family: Roboto-Medium, Roboto;
            font-weight: 500;
            font-size: 16px;
            color: #292929;
            line-height: 22px;
            text-align: left;
            font-style: normal;
        }

        span {
            font-family: Roboto, Roboto;
            font-weight: 400;
            font-size: 14px;
            color: #555555;
            line-height: 22px;
            text-align: left;
            font-style: normal;
        }
    }

    .input-slider {
        position: absolute;
        left: 50%;
        transform: translateX(-50%);
        bottom: 25px;
        display: flex;
        flex-direction: row;
        z-index: 1;

        &::v-deep>span {
            display: none;
        }

        &::v-deep .slider-warp {
            margin: 0;
            width: 300px;

            span::before {
                display: none;
            }

            B {
                width: 22px;
                height: 22px;
                border-radius: 22px;
            }
        }

        &::v-deep input {
            position: relative;
            margin-left: 24px;
            height: 32px;
            width: 68px;
            padding-left: 8px;
            padding-right: 10px;
            text-align: left;
            border-radius: 6px;
        }

        &:after {
            content: '%';
            position: absolute;
            right: 8px;
            top: 50%;
            transform: translateY(-50%);
        }
    }
}
</style>
